package test;

import java.io.FileInputStream;
import java.util.Date;
import java.util.Enumeration;

import net.jxta.document.AdvertisementFactory;
import net.jxta.document.MimeMediaType;
import net.jxta.endpoint.Message;
import net.jxta.endpoint.MessageElement;
import net.jxta.endpoint.Message.ElementIterator;
import net.jxta.exception.PeerGroupException;
import net.jxta.peergroup.PeerGroup;
import net.jxta.peergroup.PeerGroupFactory;
import net.jxta.pipe.InputPipe;
import net.jxta.pipe.PipeMsgEvent;
import net.jxta.pipe.PipeMsgListener;
import net.jxta.pipe.PipeService;
import net.jxta.protocol.PipeAdvertisement;
import net.jxta.impl.endpoint.WireFormatMessage;
import net.jxta.impl.endpoint.WireFormatMessageFactory;
import net.jxta.util.CountingOutputStream;
import net.jxta.util.DevNullOutputStream;
/**
 * this application creates an instance of an input pipe,
 * and waits for msgs on the input pipe
 *
 */

public class PipeListener implements PipeMsgListener {

    static PeerGroup netPeerGroup = null;
    private final static String SenderMessage = "PipeListenerMsg";

    private PipeService pipe;
    private PipeAdvertisement pipeAdv;
    private InputPipe pipeIn = null;

    /**
     *  main
     *
     * @param  args  command line args
     */
    public static void main(String args[]) {

        PipeListener myapp = new PipeListener();
        myapp.startJxta();
        myapp.run();
    }
    public static void printMessageStats(Message msg, boolean verbose) {
        try {
            CountingOutputStream cnt;
            ElementIterator it = msg.getMessageElements();
            System.out.println("------------------Begin Message---------------------");
            WireFormatMessage serialed = WireFormatMessageFactory.toWire(
                                             msg,
                                             new MimeMediaType("application/x-jxta-msg"), (MimeMediaType[]) null);
            System.out.println("Message Size :" + serialed.getByteLength());
            while (it.hasNext()) {
                MessageElement el = (MessageElement) it.next();
                String eName = el.getElementName();
                cnt = new CountingOutputStream(new DevNullOutputStream());
                el.sendToStream(cnt);
                long size = cnt.getBytesWritten();
                System.out.println("Element " + eName + " : " + size);
                if (verbose) {
                    System.out.println("["+el+"]");
                }
            }
            System.out.println("-------------------End Message----------------------");
        } catch (Exception e) {
            e.printStackTrace();

        }
    }

    /**
     * wait for msgs
     *
     */

    public void run() {

        try {
            // the following creates the inputpipe, and registers "this"
            // as the PipeMsgListener, when a message arrives pipeMsgEvent is called
            System.out.println("Creating input pipe");
            pipeIn = pipe.createInputPipe(pipeAdv, this);
        } catch (Exception e) {
            return;
        }
        if (pipeIn == null) {
            System.out.println(" cannot open InputPipe");
            System.exit(-1);
        }
        System.out.println("Waiting for msgs on input pipe");
    }


    /**
     * Starts jxta
     *
     */
    private void startJxta() {
        try {
            // create, and Start the default jxta NetPeerGroup
            netPeerGroup = PeerGroupFactory.newNetPeerGroup();

            // uncomment the following line if you want to start the app defined
            // the NetPeerGroup Advertisement (by default it's the shell)
            // at which case you must include jxtashell.jar in the classpath
            // in this case we want use jxta directly.

            // netPeerGroup.startApp(null);

        }
        catch (PeerGroupException e) {
            // could not instanciate the group, print the stack and exit
            System.out.println("fatal error : group creation failure");
            e.printStackTrace();
            System.exit(1);
        }

        pipe = netPeerGroup.getPipeService();
        System.out.println("Reading in pipe_entree.adv");
        try {
            FileInputStream is = new FileInputStream("pipe_entree.adv");
            pipeAdv = (PipeAdvertisement) AdvertisementFactory.newAdvertisement(MimeMediaType.XMLUTF8, is);
            is.close();
        } catch (Exception e) {
            System.out.println("failed to read/parse pipe advertisement");
            e.printStackTrace();
            System.exit(-1);
        }
    }

    /**
     * By implementing PipeMsgListener, define this method to deal with
     * messages as they arrive
     */

    public void pipeMsgEvent(PipeMsgEvent event) {

        Message msg=null;
        try {
            // grab the message from the event
            msg = event.getMessage();
            if (msg == null) {
                return;
            }
            printMessageStats(msg, true);
        } catch (Exception e) {
            e.printStackTrace();
            return;
        }

        // get all the message elements
        Message.ElementIterator en = msg.getMessageElements();
        if (!en.hasNext()) {
            return;
        }

        // get the message element named SenderMessage
        MessageElement msgElement = msg.getMessageElement(null, SenderMessage);
        // Get message
        if (msgElement.toString() == null) {
            System.out.println("null msg received");
        } else {
            Date date = new Date(System.currentTimeMillis());
            System.out.println("Message received at :"+ date.toString());
            System.out.println("Message  created at :"+ msgElement.toString());
        }
    }

}


